﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;

public abstract class Remote
{
    protected IPEndPoint m_EndPoint;
    public IPEndPoint ipEndPoint => m_EndPoint;

    protected ServerSocket m_SocketServer;
    public ServerSocket serverSocket => m_SocketServer;

    public NetMessageDispacher messageDispacher { get; set; }

    public Action<byte[]> receiveDataHandler;
    //public abstract bool connected{ get;}

    public long clientId;

    public long userID;

    public Remote(long clientId,IPEndPoint endPoint,ServerSocket serverSocket)
    {
        m_EndPoint = endPoint;
        m_SocketServer = serverSocket;
    }

    public void OnProcessMessageData(byte[] messageData)
    {
        if (receiveDataHandler != null)
        {
            receiveDataHandler.Invoke(messageData);
        }
        else
        {
            MessagePacket netMessage = new MessagePacket();
            netMessage.Read(messageData);
            //    netMessage.Read(receivedBytes, 0, count);

            if (netMessage == null)
            {
                GameDebug.LogError($"无法解析：{BitConverter.ToString(messageData)}");
            }
//#if DEBUG
//            if (netMessage.key != "NetRequest_Ping")
//            {
//                GameDebug.Log($" 收到 {netMessage.key}：\n" + BitConverter.ToString(netMessage.data));
//                if (messageDispacher != null)
//                {
//                    GameDebug.Log($" messageDispacher  all keys：{messageDispacher.netHandlerDict.Keys.AsList().GetListStr()}");
//                }
//            }
//#endif
            if (messageDispacher != null)
                messageDispacher.OnReceive(this, netMessage);
        }
    }

    MessagePacket m_CurSendMessage;
    Queue<MessagePacket> m_MsgSendQueue = new Queue<MessagePacket>();

    public void Send(MessagePacket _msg)
    {
        lock (m_MsgSendQueue)
        {
            //GameDebug.Log($"包{_msg.key} 入队");
            m_MsgSendQueue.Enqueue(_msg);
   
            // in sending
            if (m_CurSendMessage != null)
            {
                //GameDebug.Log($"当前有包在发，{_msg.key} 等待");
                Monitor.Wait(m_MsgSendQueue);
            }

            if (m_MsgSendQueue.Count <= 0)
            {
                GameDebug.LogShowy("无可发的包，返回");
                return;
            }
            m_CurSendMessage = m_MsgSendQueue.Dequeue();
        }

        MessagePacket msg = m_CurSendMessage;

        msg.time = CommonFunctions.GetTimeStamp();

        byte[] bytes = msg.Write();
#if DEBUG
        //if (msg.key == "NetEvent_FrameData")
        //{
        //    GameDebug.Log($"NetEvent_FrameData 发送的数据CRC是：{CRC32.GetCRC32(bytes)}  长度:{bytes.Length}");

        //    //byte[] data = CommonFunctions.GetBase64EncodeBytes(bytes);
        //    //var test = CommonFunctions.GetBase64DecodeBytes(data);
        //    GameDebug.Log($"test    bytes:{bytes.Length}");
        //}
        //else if (msg.key == "UserJoinMatch")
        //{
        //    GameDebug.Log("UserJoinMatch 发送：\n" + BitConverter.ToString(bytes));
        //}
        //else if (msg.key == "MatchRoomUsers")
        //{
        //    GameDebug.Log("MatchRoomUsers 发送：\n" + BitConverter.ToString(bytes));
        //}
        //else 
        //if (msg.key == "NetEvent_Opt")
        //{
        //    GameDebug.Log($"NetEvent_Opt 发送：seq:{msg.seq}  address:{this.ipEndPoint} ");
        //}
        ////else if (msg.key == "UpdateDiamond")
        ////{
        ////    GameDebug.Log($"NetEvent_UpdateDiamond 发送：seq:{msg.seq}  address:{this.ipEndPoint} \n{BitConverter.ToString(msg.data)}");
        ////}
        ////else if (msg.key == "UpdateSkin")
        ////{
        ////    GameDebug.Log($"NetEvent_UpdateSkin 发送：seq:{msg.seq}  address:{this.ipEndPoint} \n{BitConverter.ToString(msg.data)}");
        ////}
#endif

        if (m_SocketServer != null)
        {
            //GameDebug.Log($"send to {this.ipEndPoint}  socket:{m_SocketServer.socket?.GetHashCode()}  time:{msg.time}  key:{msg.key}");

            m_SocketServer.SendPacket(bytes, this.ipEndPoint);
            Thread.Sleep(5);
        }
        else
        {
            GameDebug.LogError($"m_SocketServer == null");
        }

        lock (m_MsgSendQueue)
        {
            //GameDebug.Log($"msg:{msg.key}  发送完毕，唤起等待队列");

            m_CurSendMessage = null;
            Monitor.Pulse(m_MsgSendQueue);
        }
    }

    public void SendData(byte[] data)
    {
        m_SocketServer._SendData(data, this.ipEndPoint);
    }

    public void Update()
    {
        if (!this.serverSocket.connected)
        {
            GameDebug.LogError($"{this.userID} 断开了连接");
        }
    }


}

